#ifndef MCT8316A_DRIVER_H
#define MCT8316A_DRIVER_H

#include "MCT8316AReg.h"
#include "bsp_iic.h"
#include <stdint.h>
#include "stdlib.h"
#include "string.h"

typedef struct
{
    float speed;
} MCT8316A_measure_s;

typedef struct
{
    uint32_t ISD_SWITCH;      // ISD EN/DIS, Be found in MCT8316AReg.h
    uint32_t BREAK_SWITCH;    // Break EN/DIS, Be found in MCT8316AReg.h
    uint32_t HiZ_SWITCH;      // Hi-Z EN/DIS, Be found in MCT8316AReg.h
    uint32_t RVS_SWITCH;      // Reverse Drive EN/DIS, Be found in MCT8316AReg.h
    uint32_t RESYNC_SWITCH;   // Resynchronization EN/DIS, Be found in MCT8316AReg.h
    uint32_t STAT_BRK_SWITCH; // Enable or disable brake during stationary, Be found in MCT8316AReg.h
    uint32_t STAT_DETECT_THR; // Stationary BEMF detection threshold, Be found in MCT8316AReg.h
} ISD_CONFIG_s;

typedef struct
{
    uint32_t MTR_STARTUP;         // Motor Start-up Method, Be found in MCT8316AReg.h
    uint32_t ALIGN_RAMP_RATE;     // Align voltage ramp rate, Be found in MCT8316AReg.h
    uint32_t ALIGN_TIME;          // Align time, Be found in MCT8316AReg.h
    uint32_t ALIGN_CURR_THR;      // Align current threshold, Be found in MCT8316AReg.h
    uint32_t IPD_CLK_FREQ;        // IPD clock freqquency, Be found in MCT8316AReg.h
    uint32_t IPD_CURR_THR;        // IPD current threshold (IPD current threshold (A) = IPD_CURR_THR / CSA_GAIN), Be found in MCT8316AReg.h
    uint32_t IPD_RLS_MODE;        // IPD release mode, Be found in MCT8316AReg.h
    uint32_t IPD_ADV_ANGLE;       // IPD advance angle, Be found in MCT8316AReg.h
    uint32_t IPD_REPEAT;          // Number of times IPD is executed, Be found in MCT8316AReg.h
    uint32_t SLOW_FIRST_CYC_FREQ; // Slow first cycle frequency, Be found in MCT8316AReg.h
} MOTOR_STARTUP1_s;

typedef struct
{
    uint32_t OL_current_limit_conf; // Open loop current limit configuration, Be found in MCT8316AReg.h
    uint32_t OL_ILIMIT;             //  Open loop current limit (OL current threshold (A) = OL_CURR_THR / CSA_GAIN)
    uint32_t OL_DUTY_LIMIT;         // Duty cycle limit during open loop, Be found in MCT8316AReg.h
    uint32_t OL_ACC_A1;             // Open loop acceleration A1, Be found in MCT8316AReg.h
    uint32_t OL_ACC_A2;             // Open loop acceleration A2, Be found in MCT8316AReg.h
    uint32_t OPN_CL_HANDOFF_THR;    // Open loop to closed loop handoff threshold, Be found in MCT8316AReg.h
    uint32_t AUTO_HANDOFF;          // Automatic handoff enable, Be found in MCT8316AReg.h
    uint32_t FIRST_CYCLE_FREQ_SEL;  // First cycle frequency select, Be found in MCT8316AReg.h
    uint32_t MIN_DUTY;              // Minimum operational duty cycle, Be found in MCT8316AReg.h
} MOTOR_STARTUP2_s;

typedef struct
{
    uint32_t COMM_CONTROL;      // Trapezoidal commutation mode, Be found in MCT8316AReg.h
    uint32_t CL_ACC;            // Closed loop acceleration rate, Be found in MCT8316AReg.h
    uint32_t CL_DEC;            // Closed loop deceleration rate, Be found in MCT8316AReg.h
    uint32_t PWM_FREQ_OUT;      // Output PWM switching frequency
    uint32_t LD_ANGLE_POLARITY; // LD angle polarity, Be found in MCT8316AReg.h
    uint32_t LD_ANGLE;          // Lead angle, 8-1bit, lead angle = LD_ANGLE * 0.12deg, Be found in MCT8316AReg.h
} CLOSED_LOOP1_s;

typedef struct
{
    uint32_t FG_SEL;               // FG output selection, Be found in MCT8316AReg.h
    uint32_t FG_DIV_FACTOR;        // FG division factor, Be found in MCT8316AReg.h
    uint32_t FG_CONFIG;            // FG output configuration, Be found in MCT8316AReg.h
    uint32_t FG_BEMF_THR;          // FG output BEMF threshold, Be found in MCT8316AReg.h
    uint32_t MTR_STOP;             // Motor stop method, Be found in MCT8316AReg.h
    uint32_t MTR_STOP_BRK_TIME;    // Brake time during motor stop, Be found in MCT8316AReg.h
    uint32_t ACT_SPIN_BRK_THR;     // Duty cycle threshold for motor stop using active spin down, low- and high-side braking
    uint32_t BRAKE_DUTY_THRESHOLD; // Duty cycle threshold for BRAKE pin based low-side braking, Be found in MCT8316AReg.h
    uint32_t AVS_SWITCH;           // Automatic voltage scaling (AVS) enable, Be found in MCT8316AReg.h
    uint32_t CBC_ILIMIT;           // CBC current limit, Cycle by Cycle (CBC) current limit (CBC current limit (A) = CBC_ILIMIT / CSA_GAIN) Be found in MCT8316AReg.h
} CLOSED_LOOP2_s;

typedef struct
{
    uint32_t BEMF_THRESHOLD2;      // BEMF threshold for integration based commutation during falling floating phase voltage, Be found in MCT8316AReg.h
    uint32_t BEMF_THRESHOLD1;      // BEMF threshold for integration based commutation during rising floating phase voltage, Be found in MCT8316AReg.h
    uint32_t INTEG_ZC_METHOD;      // Integration zero crossing method, Be found in MCT8316AReg.h
    uint32_t DEGAUSS_MAX_WIN;      // Maximum window for degauss detection, Be found in MCT8316AReg.h
    uint32_t DYN_DEGAUSS;          // Dynamic degauss detection, Be found in MCT8316AReg.h
    uint32_t INTEG_DUTY_THR_HIGH;  // Duty cycle above which commutation method switches from ZC to integration, Be found in MCT8316AReg.h
    uint32_t INTEG_DUTY_THR_LOW;   // Duty cycle below which commutation method switches from integration to ZC, Be found in MCT8316AReg.h
    uint32_t INTEG_CYCL_THR_HIGH;  // Number of BEMF samples per 30° above which commutation method switches from ZC to integration, Be found in MCT8316AReg.h
    uint32_t INTEG_CYCL_THR_LOW;   // Number of BEMF samples per 30° below which commutation method switches from integration to ZC, Be found in MCT8316AReg.h
    uint32_t DYN_DGS_FILT_COUNT;   // Number of samples needed for dynamic degauss check, Be found in MCT8316AReg.h
    uint32_t DYN_DGS_UPPER_LIM_VM; // Dynamic degauss voltage upper bound, Be found in MCT8316AReg.h
    uint32_t DYN_DGS_LOWER_LIM;    // Dynamic degauss voltage lower bound, Be found in MCT8316AReg.h
} CLOSED_LOOP3_s;

typedef struct
{
    uint32_t SPD_POWER_KP;     // Speed/ Power loop Kp (Kp = SPD_LOOP_KP / 10000) 29-20bit，注意要位移
    uint32_t SPD_POWER_KI;     // Speed/ Power loop Ki (Ki = SPD_LOOP_KI / 10000) 19-10bit，注意要位移
    uint32_t SPD_POWER_V_MAX;  // Upper saturation limit for speed/ power loop, Be found in MCT8316AReg.h
    uint32_t SPD_POWER_V_MIN;  // Lower saturation limit for speed/power loop, Be found in MCT8316AReg.h
    uint32_t CLOSED_LOOP_MODE; // Closed loop mode, Be found in MCT8316AReg.h
} CONST_SPEED_s;

typedef struct
{
    uint32_t MAX_SPEED; // 30-15bit, Maximum Speed (Maximum Speed (Hz) = MAX_SPEED / 16)
    uint32_t MAX_POWER; // 13-4bit,  Maximum power (Maximum power (W) = MAX_POWER / 4)
} CONST_PWR_s;

typedef struct
{
    uint32_t OL_HANDOFF_CYCLES; // Open loop handoff cycles, Be found in MCT8316AReg.h
} TRAP_CONFIG1_s;
typedef struct
{
    uint32_t MTR_LCK_MODE; // Motor lock mode, Be found in MCT8316AReg.h
} FAULT_CONFIG1_s;

typedef struct
{
    uint32_t LOCK1;           // Lock 1 (Abnormal Speed) Enable, Be found in MCT8316AReg.h
    uint32_t LOCK2;           // Lock 2 (Loss of Sync) Enable, Be found in MCT8316AReg.h
    uint32_t LOCK3;           // Lock 3 (No Motor) Enable, Be found in MCT8316AReg.h
    uint32_t LOCK_ABN_SPEED;  // Abnormal speed lock threshold, Be found in MCT8316AReg.h
    uint32_t LOSS_SYNC_TIMES; // Loss of sync lock threshold, Be found in MCT8316AReg.h
    uint32_t NO_MTR_THR;      // No motor lock current threshold (No motor lock current threshold (A) = NO_MTR_THR / CSA_GAIN), Be found in MCT8316AReg.h
} FAULT_CONFIG2_s;

typedef struct
{
    uint32_t DACOUT1_VAR_ADDR; // DACOUT1 variable address, Be found in MCT8316AReg.h
    uint32_t DACOUT2_VAR_ADDR; // DACOUT2 variable address, Be found in MCT8316AReg.h
    uint32_t SPD_CTRL_MODE;    // Speed control mode, Be found in MCT8316AReg.h
} PIN_CONFIG1_s;

typedef struct
{
    uint32_t DAC_SOX_CONFIG;  // DACOUT2, SOA, SOB, SOC configuration, Be found in MCT8316AReg.h
    uint32_t DAC_XTAL_CONFIG; // Pin 37 and pin 38 configuration, Be found in MCT8316AReg.h
} PIN_CONFIG2_s;

typedef struct
{
    uint32_t SLEW_RATE; // Slew rate, Be found in MCT8316AReg.h
    uint32_t CSA_GAIN;  // Current Sense Amplifier (CSA) Gain, Be found in MCT8316AReg.h
} GD_CONFIG1_s;

typedef struct
{
    uint32_t STATE;       // State, Be found in MCT8316AReg.h
    uint32_t MOTOR_SPEED; // Motor speed, Be found in MCT8316AReg.h, MOTOR_SPEED = (SYS_STATUS2[15:0] & SPEED_OUTPUT) / 10
} SYS_STATUS2_s;

typedef struct
{
    IIC_Init_Config_s iic_conf;
    ISD_CONFIG_s ISD_CONFIG;
    MOTOR_STARTUP1_s MOTOR_STARTUP1;
    MOTOR_STARTUP2_s MOTOR_STARTUP2;
    CLOSED_LOOP1_s CLOSED_LOOP1;
    CLOSED_LOOP2_s CLOSED_LOOP2;
    CLOSED_LOOP3_s CLOSED_LOOP3;
    CONST_SPEED_s CONST_SPEED;
    CONST_PWR_s CONST_PWR;
    TRAP_CONFIG1_s TRAP_CONFIG1;
    FAULT_CONFIG1_s FAULT_CONFIG1;
    FAULT_CONFIG2_s FAULT_CONFIG2;
    PIN_CONFIG1_s PIN_CONFIG1;
} MCT8316A_conf_s;

/* 发送/接收的寄存器地址与内容 */
typedef struct
{
    uint8_t addr;
    uint32_t data;
} MCT8316A_reg_s;

/* 保存MCT8316A内所有内容，用于调试 */
typedef struct
{
    IICInstance *iic_instance;
    MCT8316A_measure_s measure;
    MCT8316A_reg_s reg_message;
    uint8_t CRC_buff;
} MCT8316A_Instance_s;

MCT8316A_Instance_s *MCT8316A_Init(MCT8316A_conf_s *conf);
void MCT8316A_SetReg(MCT8316A_Instance_s *instance, MCT8316A_reg_s *reg);
void MCT8316A_GetReg(MCT8316A_Instance_s *instance, MCT8316A_reg_s *reg);

uint8_t MCT8316A_CRC(uint8_t *data, uint8_t len);
#endif